package yunquan.wang.modules.base.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import yunquan.wang.base.config.AppConfig;
import yunquan.wang.base.dao.springdata.BaseRepository;
import yunquan.wang.base.service.impl.BaseServiceImpl;
import yunquan.wang.base.spring.security.SpringSecurityUtils;
import yunquan.wang.base.utils.DateTimeUtils;
import yunquan.wang.base.utils.ZipUtils;
import yunquan.wang.modules.base.dao.BackupDatabaseDao;
import yunquan.wang.modules.base.entity.BackupDatabase;
import yunquan.wang.modules.base.service.BackupDatabaseService;

@Service("backupDatabaseService")
@Transactional(value = "jpaTransaction")
public class BackupDatabaseServiceImpl extends BaseServiceImpl<BackupDatabase>
		implements BackupDatabaseService {
	@Resource
	private BackupDatabaseDao backupDatabaseDao;

	@Override
	public BaseRepository<BackupDatabase, String> getDao() {
		return backupDatabaseDao;
	}

	public void delete(String id)
	{
		BackupDatabase bak=this.get(id);
		String zipFile = bak.getFilepath() + File.separator + bak.getFileName();
		super.delete(id);
		new File(zipFile).deleteOnExit();
	}
	@Override
	public Boolean backUpdataAll(String backName) {

		 
		String host = AppConfig.getDbhost();
		String username = AppConfig.getDbUser();
		String password = AppConfig.getDbPass();
	File errorFilepath=null;
	File backupFilePath=null;
	try {
		errorFilepath = File.createTempFile("MYSQLERROR", ".txt");
		backupFilePath = File.createTempFile(AppConfig.DB_RESTORE_SQL, ".sql");
	} catch (IOException e1) {
 
		e1.printStackTrace();
	}
	 
		String dbName = AppConfig.getDatabase();
		Integer port = AppConfig.getDbport();
		String[] ignortables = AppConfig.getDbBackIgnore();
		String dateTime = DateTimeUtils
				.getCurrentDateString(DateTimeUtils.SSFORMARTSTRING);


	 
		String ignortable = " ";
		if (ignortables.length > 0) {
			for (String ign : ignortables)
				ignortable += " --ignore-table=" + dbName + "." + ign;
		}

		String command = "mysqldump -h"
				+ host
				+ " -p"
				+ port
				+ " -u"
				+ username
				+ " -p"
				+ password
				+ " --database "
				+ dbName
				+ " --opt --skip-comments --complete-insert --hex-blob --default-character-set=utf8"
				+ " --result-file=" + backupFilePath.getAbsolutePath() +  ignortable
				+ " --log-error=" + errorFilepath.getAbsolutePath();

		BackupDatabase bak = new BackupDatabase();
	
		Runtime runt = Runtime.getRuntime();
 
		try {
			Process proc = runt.exec(command);
			int tag = proc.waitFor();// 等待进程终止
			if (tag == 0) {
				if (errorFilepath.getTotalSpace() != 0) {
					bak.setSuccess(false);
				}

			} else {
				bak.setSuccess(false);
			}
		} catch (IOException | InterruptedException e) {
			bak.setSuccess(false);
			e.printStackTrace();
		}
	 
		String zipFileName = AppConfig.getBackDbFilePath() + File.separator + dateTime + ".zip";
		File zip = new File(zipFileName);
		try {
			ZipUtils.zip(backupFilePath, zip);
			Long size = backupFilePath.length() / 1024;
			bak.setBackName(backName);
			bak.setFilesize(size.intValue());
			bak.setSuccess(true);
			bak.setFileName(dateTime+".zip");
		} catch (IOException e) {
			bak.setSuccess(false);
			e.printStackTrace();
		} finally
		{
			errorFilepath.deleteOnExit();
			backupFilePath.deleteOnExit();
		}
		 this.save(bak);
		return bak.getSuccess();
	}

	@Override
	public Boolean restoreData(String id) {
		BackupDatabase bak=  this.get(id);
		return restoreData(bak);
	}

	
	public BackupDatabase save(BackupDatabase entity)
	{
		entity.setCreateTime(new Date());
		entity.setFilepath(AppConfig.getBackDbFilePath());
		entity.setUserId(SpringSecurityUtils.getCurrentUserName());
		return super.save(entity);
	}
	@Override
	public Boolean restoreData(BackupDatabase bak) {
	
		 
		String fileName = bak.getFileName();
	File restore=null;
	try {
		restore = File.createTempFile(AppConfig.DB_RESTORE_SQL, ".sql");
	} catch (IOException e1) {
		e1.printStackTrace();
	}
		String zipFile = bak.getFilepath() + File.separator + fileName;
		File zip = new File(zipFile);
		try {
			ZipFile zf = new ZipFile(zip);
			Enumeration enu = zf.entries();
			ZipEntry file = (ZipEntry) enu.nextElement();
			InputStream fi = zf.getInputStream(file);
			FileOutputStream out = new FileOutputStream(restore);
			byte[] c = new byte[1024];
			int slen;
			while ((slen = fi.read(c, 0, c.length)) != -1) {
				out.write(c, 0, slen);
			}
			zf.close();
			out.close();
			fi.close();
			String command = "mysql -h" + AppConfig.getDbhost() + " -p"
					+ AppConfig.getDbport() + " -u"
					+ AppConfig.getDbUser() + " -p"
					+ AppConfig.getDbPass() + " < " + restore.getAbsolutePath();
			Runtime runt = Runtime.getRuntime();
			Process proc = runt.exec(command);
			int tag = proc.waitFor();// 等待进程终止
			if (tag == 0) {
				return true;
			} else {
				return false;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally
		{
			restore.deleteOnExit();
		}
	
		return false;
	}

 

	// mysqldump -hlocalhost -p3306 -uroot -p741369 --opt --skip-comments
	// --complete-insert --hex-blob --result-file=/home/wang/mysqlback.sql
	// --default-character-set=utf8 --ignore-table=yiding.BASE_CODEVALUE
	// --database yiding --log-error=/home/wang/mysqlerror.txt
	//
	// 更改mysql的配置文件my.cnf ,导入大文件
	// 将max_allowed_packet改成1024M
	//
	// mysql -hlocalhost -p3306 -uroot -p741369 < /home/wang/mysqlback.sql

}
